package com.watson.demo.mybatisplus.service.impl;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.watson.demo.mybatisplus.entity.TUser;
import com.watson.demo.mybatisplus.mapper.TUserMapper;
import com.watson.demo.mybatisplus.service.TUserService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

/**
 * //如果数据源注解写在类上，就默认方法中所有的方法都使用这个数据源，
 * 如果方法还有数据源设置，则优先使用方法上的数据源
 *
 * 通过查看dynamic-datasource-spring-boot-starter的源码发现其中有几个比较重要的类：
 * 1.com.baomidou.dynamic.datasource.spring.boot.autoconfigur.DynamicDataSourceAutoConfiguration配置类
 * 1.com.baomidou.dynamic.datasource.aop.DynamicDataSourceAnnotationInterceptor
 * 实现了Spring的MethodInterceptor接口实现了Spring的AOP功能；
 * 2.com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder
 * 创建了线程本地变量LOOKUP_KEY_HOLDER来存放当前线程所访问的数据源；
 * 3.com.baomidou.dynamic.datasource.DynamicRoutingDataSource继承了抽象类com.baomidou.dynamic.datasource.AbstractRoutingDataSource；
 * 抽象类com.baomidou.dynamic.datasource.AbstractRoutingDataSource又继承了com.baomidou.dynamic.datasource.AbstractDataSource；
 * com.baomidou.dynamic.datasource.AbstractDataSource则是实现了javax.sql.DataSource。
 * AbstractRoutingDataSource最终实现了DataSource的getConnection()方法来提供数据库连接
 *
 * 具体步骤：
 * 首先，项目启动的时候加载配置类DynamicDataSourceAutoConfiguration，注入了DynamicRoutingDataSource，并调用了DynamicRoutingDataSource的init()方法完成了数据源的初始化，将数据源放到了DynamicRoutingDataSource对象中的dataSourceMap中。
 * 当发起请求时，DynamicDataSourceAnnotationInterceptor拦截到添加了@DS注解的方法，将@DS注解的value存放到DynamicDataSourceContextHolder的LOOKUP_KEY_HOLDER中，当请求获取数据库连接时，AbstractRoutingDataSource的getConnection()方法，从LOOKUP_KEY_HOLDER中取到当前配置的数据源
 * 名称，然后从dataSourceMap中获取到DataSource对象，然后dataSource.getConnection()获取数据库连接。
 *
 * @author: llun
 * @date: 2022/2/15 8:13
 * @version: 1.0
 */
@Service
//@DS("master")
public class TUserServiceImpl extends ServiceImpl<TUserMapper, TUser> implements TUserService {
    @Resource
    TUserMapper studentMapper;

    // 使用master的数据源 插入库
    @Override
    @DS("master")
    public boolean insertTUser(TUser entity) {
        return save(entity);
    }

    // 使用slave_1的数据源查询数据
    @Override
    @DS("slave_1")
    public List<TUser> listTUser() {
        return list();
    }

}
